home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / NeoIntroTCL3.0 folder / TCL / NeoDemo / Source / CNeoDLOGDialog.cp < prev    next >
Encoding:
Text File  |  1994-08-01  |  28.9 KB  |  1,021 lines  |  [TEXT/KAHL]

  1. /******************************************************************************
  2.  CNeoDLOGDialog.c
  3.  
  4.         Subclass of CDialog that can be create from DLOG/DITL
  5.         resources. The standard dialog items are represented
  6.         by their closest TCL analogs.
  7.  
  8.     SUPERCLASS = CDialog
  9.  
  10.     Copyright © 1991 Symantec Corporation. All rights reserved.
  11.     Copyright © 1992 NeoLogic Systems.  All rights reserved.
  12.  
  13.  
  14.  ******************************************************************************/
  15.  
  16. #include "NeoTypes.h"
  17. #include "Constants.h"
  18. #include "Commands.h"
  19. #include "TBUtilities.h"
  20. #include <CList.h>
  21. #include <CCheckBox.h>
  22. #include <CRadioControl.h>
  23. #include <CIntegerText.h>
  24. #include <CIconPane.h>
  25. #include <CPaneBorder.h>
  26. #include <CRadioGroupPane.h>
  27. #include <CBartender.h>
  28. #include <CScrollBar.h>
  29. #include CNeoDatabaseH
  30. #include "CNeoPopupPane.h"
  31. #include "CNeoDialogText.h"
  32. #include "CNDPicture.h"
  33. #include "CNeoDLOGDialog.h"
  34. #include "CNDButton.h"
  35. #include "CNeoDemoApp.h"
  36. #include "CNeoDemoDoc.h"
  37. #include "CNDFilePicture.h"
  38. #include "CNeoDemoScrollPane.h"
  39. #include "CNDImage.h"
  40.  
  41. #define SysFontFam  ((short*) 0x0BA6)
  42. #define SysFontSize ((short*) 0x0BA8)
  43. #define LastSpExtra ((long*)  0x0B4C)
  44.  
  45. #define kUserType                2        /* popup menu dialog ID */
  46. #define kPICTName                4
  47. #define ktextBy                    9
  48. #define ktextDate                10
  49. #define kUserFilm                11
  50. #define ktextCatalog            12
  51. #define ktextKeywords            13
  52. #define kUserBody                14
  53. #define kUserFocal                15
  54. #define kUserFStop                16
  55. #define kUserExposure            17
  56. #define ksearchText                19
  57. #define kTextInfo                21        /* <picture#>/<max#> dialog ID */
  58. #define kUserLineDivider1        22
  59. #define kUserLineDivider2        23
  60. #define ksigPICT                24        /* signal flag picture dialog ID */
  61. #define kType                    25        /* displays the type of the current picture */
  62.  
  63. #define kTypePopupMenuID        20        /* type popup resource ID */
  64. #define kFilmPopupMenuID        21        /* film popup resource ID */
  65. #define kBodyPopupMenuID        22
  66. #define kFocalPopupMenuID        23
  67. #define kFStopPopupMenuID        24
  68. #define kExposurePopupMenuID    25
  69.  
  70. typedef struct tItemList
  71. {
  72.     short        maxIndex;
  73.     tDITLItem    items[1];
  74.  
  75. } tItemList, *tItemListPtr, **tItemListHndl;
  76.  
  77. extern CBartender *gBartender;
  78.  
  79. static void CollectUntil(char delimiter, StringPtr text, short *index,
  80.                 StringPtr returnStr);
  81.  
  82. static short itemID;    /* current dialog item ID during initialization */
  83.  
  84. /******************************************************************************
  85.  CNeoDLOGDialog
  86.  
  87.      Initialize a dialog window from DLOG/DITL resources.
  88. ******************************************************************************/
  89.  
  90. CNeoDLOGDialog::CNeoDLOGDialog(short aDLOGid, CDesktop *anEnclosure, CDirector *aSupervisor)
  91. {
  92.     Rect        boundsRect;
  93.     SignedByte    savedState;
  94.     Boolean        makeScrollable;
  95.     DialogTHndl dlogTemplate;
  96.  
  97.     CNeoApp::FNumWindowsOpen++;
  98.  
  99.     fStaticTextFont = fEditTextFont = geneva;    /* use the system font */
  100.     fStaticTextSize = fEditTextSize = 9;        /* use TE's default size */
  101.     fDefaultBorderPen = 1;                        /* default to border of 1 pixel */
  102.  
  103.  
  104.                                                 /* Get the DLOG resource template */
  105.     FailNILRes(dlogTemplate = (DialogTHndl)GetResource('DLOG', aDLOGid));
  106.  
  107.                                                 /* Get window size from the template */
  108.     boundsRect = (**dlogTemplate).boundsRect;
  109.  
  110.     /* If the procID is documentProc or zoomDocProc then give the window */
  111.     /* horizontal and vertical scroll bars and a size box. */
  112.  
  113.     procID = (**dlogTemplate).procID;
  114.     makeScrollable = (procID == documentProc) || (procID == zoomDocProc);
  115.  
  116.     CDialog::INewDialog(&boundsRect, kNotVisible, procID, (**dlogTemplate).goAwayFlag, anEnclosure, aSupervisor);
  117.     MakePanorama(makeScrollable, makeScrollable, makeScrollable);
  118.  
  119.                                                 /* Get the DITL resource and create all the dialog items */
  120.     AddDITLItems((**dlogTemplate).itemsID, 0);
  121.  
  122.     ((CNeoDemoDoc *)aSupervisor)->fBottomLine = boundsRect.bottom-boundsRect.top;    /* full length */
  123.     ChangeSize(macPort->portRect.right - macPort->portRect.left, ((CNeoDemoDoc *)aSupervisor)->fDivideLine -2);
  124.  
  125. }    /* CDialog::CNeoDLOGDialog */
  126.  
  127. CNeoDLOGDialog::~CNeoDLOGDialog(void)
  128. {
  129.     CNeoApp::FNumWindowsOpen--;
  130. }
  131.  
  132. /******************************************************************************
  133.  AddDITLItems
  134.  
  135.      Parse the DITL resource, and create the appropriate TCL panes.
  136.      A separate method is called for each item type, so it is not usually
  137.      necessary to override this method.
  138.  
  139. ******************************************************************************/
  140.  
  141. void CNeoDLOGDialog::AddDITLItems(short DITLid, long baseID)
  142. {
  143.     tItemListHndl    itemList = NULL;
  144.     SignedByte        savedState;
  145.     short            currIndex, maxIndex, dataSize;
  146.     Boolean            fDisabled;
  147.     tDITLItem *    ditlItem;
  148.     short            itemWidth, itemHeight;
  149.     LongPt            itemTopLeft;
  150.     CView            *enclosure;
  151.     CPane            *newItem;
  152.  
  153.     NEOTRYTO
  154.     {
  155.                 /* Get the DITL item list                            */
  156.         itemList = (tItemListHndl) GetResource('DITL', DITLid);
  157.         FailNILRes(itemList);
  158.  
  159.         savedState = HGetState((Handle) itemList);
  160.         HLockHi((Handle)itemList);
  161.  
  162.         maxIndex = (**itemList).maxIndex; /* index of last item in list */
  163.         ditlItem = (**itemList).items;      /* point to the first DITL item */
  164.  
  165.                 /* iterate over all the items in the DITL resource        */
  166.                 /* and create the TCL panes on the fly                    */
  167.  
  168.         for (currIndex = 0; currIndex <= maxIndex; currIndex++) {
  169.             itemID = currIndex+1;  /* file local variable for the various add routines */
  170.  
  171.                 /* Is this item disabled?                                */
  172.             fDisabled = ditlItem->itemType & itemDisable;
  173.  
  174.                 /* Get size of the item, and the pad it for word        */
  175.                 /* alignment if necessary                                */
  176.  
  177.             dataSize = ditlItem->itemLength;
  178.             if (dataSize & 1)
  179.                 ++dataSize;
  180.  
  181.                 /* Find the "best fit" enclosure for the new item        */
  182.  
  183.             enclosure = FindEnclosingView(&ditlItem->itemRect);
  184.  
  185.                 /* Get the dimensions for the new item                    */
  186.  
  187.             itemWidth = ditlItem->itemRect.right - ditlItem->itemRect.left;
  188.             itemHeight = ditlItem->itemRect.bottom - ditlItem->itemRect.top;
  189.  
  190.                 /* If the enclosure for the new item is not the dialog     */
  191.                 /* itself, then we should transform the top left to the */
  192.                 /* enclosure's coordinates.    Note that the item rect in     */
  193.                 /* ditlItem is passed unmodified to    the item creation     */
  194.                 /* methods.                                                */
  195.  
  196.             ((CPane*) enclosure)->WindToFrame(topLeft(ditlItem->itemRect),
  197.                                 &itemTopLeft);
  198.  
  199.                 /* Switch on the item type. We must strip off the         */
  200.                 /* enable bit to do so.                                    */
  201.  
  202.             switch(ditlItem->itemType & 0x7F)
  203.             {
  204.                         /* User Items        */
  205.                 case userItem:
  206.                     newItem = AddDITLUserItem(itemWidth, itemHeight, itemTopLeft.h,
  207.                                 itemTopLeft.v, enclosure, ditlItem);
  208.                     break;
  209.  
  210.                         /* Push Buttons        */
  211.                 case ctrlItem + btnCtrl:
  212.                     newItem = AddDITLPushBtn(itemWidth, itemHeight, itemTopLeft.h,
  213.                                 itemTopLeft.v, enclosure, ditlItem);
  214.                     break;
  215.  
  216.                         /* Check boxes        */
  217.                 case ctrlItem + chkCtrl:
  218.                     newItem = AddDITLCheckBox(itemWidth, itemHeight, itemTopLeft.h,
  219.                                 itemTopLeft.v, enclosure, ditlItem);
  220.                     break;
  221.  
  222.                         /* Radio Buttons    */
  223.                 case ctrlItem + radCtrl:
  224.                     newItem = AddDITLRadioBtn(itemWidth, itemHeight, itemTopLeft.h,
  225.                                 itemTopLeft.v, enclosure, ditlItem,
  226.                                 currIndex + baseID + 1);
  227.                     break;
  228.  
  229.                         /* 'CNTL' Resource Controls */
  230.                 case ctrlItem + resCtrl:
  231.                     newItem = AddDITLResControl(itemWidth, itemHeight, itemTopLeft.h,
  232.                                 itemTopLeft.v, enclosure, ditlItem);
  233.                     fDisabled=TRUE;    /* don't want clicks, initially */
  234.                     break;
  235.  
  236.                         /* Static text        */
  237.                 case statText:
  238.                     newItem = AddDITLStatText(itemWidth, itemHeight, itemTopLeft.h,
  239.                                 itemTopLeft.v, enclosure, ditlItem);
  240.                     break;
  241.  
  242.                         /* Edit text        */
  243.                 case editText:
  244.                     newItem = AddDITLEditText(itemWidth, itemHeight, itemTopLeft.h,
  245.                                 itemTopLeft.v, enclosure, ditlItem);
  246.                     break;
  247.  
  248.                         /* Icons            */
  249.                 case iconItem:
  250.                     newItem = AddDITLIcon(itemWidth, itemHeight, itemTopLeft.h,
  251.                                 itemTopLeft.v, enclosure, ditlItem);
  252.                     break;
  253.  
  254.                         /* Pictures            */
  255.                 case picItem:
  256.                     newItem = AddDITLPicture(itemWidth, itemHeight, itemTopLeft.h,
  257.                                 itemTopLeft.v, enclosure, ditlItem);
  258.                     break;
  259.  
  260.                 default:
  261.                     newItem = NULL;
  262.                     break;
  263.             }
  264.  
  265.             if (newItem)
  266.             {
  267.                 /* Set the view ID of the new dialog item to its index in the DITL + */
  268.                 /* the base ID supplied by the caller.                              */
  269.  
  270.                 newItem->SetID(currIndex + baseID + 1);
  271.                 if (fDisabled)
  272.                     /* +++ disable item? */;
  273.                 else
  274.                 {
  275.                     newItem->SetWantsClicks(TRUE);
  276.                 }
  277.             }
  278.  
  279.                 /* bypass C pointer arithmetic to point to next item */
  280.             ditlItem = (tDITLItem *)(((long) ditlItem) + dataSize + (sizeof(*ditlItem) - sizeof(ditlItem->itemData)));
  281.  
  282.         }
  283.     }
  284.     NEOCLEANUP {
  285.         if (itemList)
  286.             HSetState((Handle) itemList, savedState);
  287.     }
  288.     NEOENDTRYTO;
  289.  
  290. }    /* CNeoDLOGDialog::AddDITLItems */
  291.  
  292. /******************************************************************************
  293.  FindEnclosingView
  294.  
  295.      Find the view that completely encloses the given rectangle. DITLs have
  296.      no concept of nested items, but we can allow nested views to be specified
  297.      by checking whether the rectangle of an new item is completely
  298.      enclosed by the rectangle of any existing items.
  299.      The rectangle is taken to be in Window coordinates.
  300. ******************************************************************************/
  301.  
  302.     typedef struct tEnclViewInfo
  303.     {
  304.         Rect    boundsRect;
  305.         CView   *enclosingView;
  306.  
  307.     } tEnclViewInfo;
  308.  
  309.     static Boolean View_FindEnclosing(CView *view, long infoAddr)
  310.     {
  311.         CView *subview = NULL;
  312.         tEnclViewInfo *viewInfo = (tEnclViewInfo*) infoAddr;
  313.         
  314.         /* first check if the current view encloses the rect */
  315.         /* if it does, then check if any subview encloses it */
  316.         
  317.         if (view->Contains(topLeft(viewInfo->boundsRect)) &&
  318.             view->Contains(botRight(viewInfo->boundsRect)))
  319.         {
  320.             if (view->itsSubviews)
  321.             {
  322.                 subview = (CView*) view->itsSubviews->FirstSuccess1(View_FindEnclosing,
  323.                                                                     infoAddr);
  324.             }
  325.             
  326.             /* save the most specific view that encloses the rect,    */
  327.             /* either a subview of this view, or this view            */
  328.             
  329.             if (!viewInfo->enclosingView)    /* TCL 1.1.1 DLP 9/30/91 */
  330.                 viewInfo->enclosingView = subview? subview : view;
  331.             return TRUE;
  332.         }
  333.         else return FALSE;
  334.     }
  335.  
  336. CView *CNeoDLOGDialog::FindEnclosingView(Rect *boundsRect)
  337. {
  338.     CView *foundView = NULL;
  339.     tEnclViewInfo  viewInfo;
  340.  
  341.     if (itsSubviews)
  342.     {
  343.         viewInfo.boundsRect = *boundsRect;
  344.         viewInfo.enclosingView = NULL;
  345.         foundView = (CView*) itsSubviews->FirstSuccess1(View_FindEnclosing,
  346.                         (long) &viewInfo);
  347.  
  348.         /* If foundView is not nil, then some subview encloses    */
  349.         /* the rect. However, there may be a view nested within */
  350.         /* foundView that completely encloses the rect.         */
  351.         /* viewInfo.enclosingView returns the best view            */
  352.  
  353.         foundView = viewInfo.enclosingView;
  354.     }
  355.  
  356.     /* if no subview was found that completely encloses boundsRect */
  357.     /* then the enclosure defaults to the dialog itself */
  358.  
  359.     return foundView? foundView : itsPanorama;
  360.  
  361. }    /* CNeoDLOGDialog::FindEnclosingView */
  362.  
  363. /******************************************************************************
  364.  AddDITLPushBtn
  365.  
  366.      Add a button.
  367. ******************************************************************************/
  368.  
  369. CPane *CNeoDLOGDialog::AddDITLPushBtn(short aWidth, short aHeight, short hEncl,
  370.                         short vEncl, CView *enclosure, tDITLItem *ditlItem)
  371. {
  372.     CNDButton *btn;
  373.     Str255  titleStr;
  374. //    long    cmd;
  375.  
  376.     /* make a copy of the button title */
  377.  
  378.     CopyPString(&ditlItem->itemLength, titleStr);
  379.  
  380. //    /* ask the bartender to parse this string for us. */
  381. //    gBartender->ParseItemString(titleStr, &cmd);
  382.  
  383.     btn = new(CNDButton);
  384.     btn->INewButton(aWidth, aHeight, hEncl, vEncl, titleStr, TRUE,
  385.             pushButProc, enclosure, this);
  386.     SetDefaultButton(btn);
  387. //    btn->SetClickCmd(cmd);
  388.  
  389.     return btn;
  390.  
  391. }    /* CNeoDLOGDialog::AddDITLPushBtn */
  392.  
  393. /******************************************************************************
  394.  AddDITLRadioBtn
  395.  
  396.      Add a radio button.
  397. ******************************************************************************/
  398.  
  399. CPane *CNeoDLOGDialog::AddDITLRadioBtn(short aWidth, short aHeight, short hEncl,
  400.                         short vEncl, CView *enclosure, tDITLItem *ditlItem,
  401.                         long anID)
  402. {
  403.     CRadioControl *radio = new(CRadioControl);
  404.  
  405.     radio->INewRadioControl(aWidth, aHeight, hEncl, vEncl, &ditlItem->itemLength,
  406.                 TRUE, enclosure, enclosure);
  407.  
  408.     return radio;
  409.  
  410. }    /* CNeoDLOGDialog::AddDITLRadioBtn */
  411.  
  412. /******************************************************************************
  413.  AddDITLCheckBox
  414.  
  415.      Add a checkbox
  416. ******************************************************************************/
  417.  
  418. CPane *CNeoDLOGDialog::AddDITLCheckBox(short aWidth, short aHeight, short hEncl,
  419.                         short vEncl, CView *enclosure, tDITLItem *ditlItem)
  420. {
  421.     CCheckBox *check = new(CCheckBox);
  422.  
  423.     check->INewCheckBox(aWidth, aHeight, hEncl, vEncl, &ditlItem->itemLength,
  424.                         TRUE, enclosure, this);
  425.  
  426.     return check;
  427.  
  428. }    /* CNeoDLOGDialog::AddDITLCheckBox */
  429.  
  430. /******************************************************************************
  431.  AddDITLResControl
  432.  
  433.      Resource controls are not supported by this class.
  434. ******************************************************************************/
  435.  
  436. CPane *CNeoDLOGDialog::AddDITLResControl(short aWidth, short aHeight, short hEncl,
  437.                         short vEncl, CView *enclosure, tDITLItem *ditlItem)
  438. {
  439.     CNeoDemoScrollPane *scrollPane = new CNeoDemoScrollPane;
  440.     FailNIL(scrollPane);
  441.  
  442.     scrollPane->IScrollPane(enclosure,this,aWidth,aHeight,hEncl,vEncl,
  443.                             sizFIXEDSTICKY, sizFIXEDSTICKY,1,0,0);
  444.  
  445.     scrollPane->itsHorizSBar->SetMaxValue(0);    /* initially, no pictures to scroll */
  446.     scrollPane->itsHorizSBar->SetValue(0);    /* initially, no pictures to scroll */
  447.     ((CNeoDemoDoc *)itsSupervisor)->fScrollObj = scrollPane;
  448.     return ((CPane*)scrollPane);
  449.  
  450. }    /* CNeoDLOGDialog::AddDITLResControl */
  451.  
  452. /******************************************************************************
  453.  AddDITLStatText
  454.  
  455.      Add a static text item. If the item text begins with the character '@',
  456.      it is considered an overloaded item and the rest of the text is passed
  457.      to the AddOverloadedItem method.
  458.      The text font and size are controlled by the fStaticTextFont and
  459.      fStaticTextSize instance variables.
  460. ******************************************************************************/
  461.  
  462. CPane *CNeoDLOGDialog::AddDITLStatText(short aWidth, short aHeight, short hEncl,
  463.                         short vEncl, CView *enclosure, tDITLItem *ditlItem)
  464. {
  465.     CEditText            *text;
  466.     unsigned char        length;
  467.     Str255                itemText;
  468.  
  469.     /* first check for overloading of static text items        */
  470.     /* overloading is signalled by a first character of '@' */
  471.  
  472.     if ((* (char*) ditlItem->itemData) == '@')
  473.     {
  474.         length = Min(ditlItem->itemLength - 1, 255);
  475.         BlockMove(((char*) ditlItem->itemData) + 1, &itemText[1], length);
  476.         itemText[0] = length;
  477.  
  478.         return AddOverloadedItem(itemText, aWidth, aHeight, hEncl, vEncl, enclosure, ditlItem);
  479.     }
  480.     else
  481.     {
  482.         text = new(CEditText);
  483.         text->IEditText(enclosure, this, aWidth, aHeight, hEncl, vEncl, sizFIXEDSTICKY, sizFIXEDSTICKY, -1);
  484.         text->Specify(kNotEditable, kNotSelectable, kNotStylable);
  485.  
  486.         text->SetFontNumber(fStaticTextFont);
  487.  
  488.         text->SetFontSize(fStaticTextSize);
  489.  
  490.         if (ditlItem->itemLength)
  491.             text->SetTextPtr((Ptr) ditlItem->itemData, ditlItem->itemLength);
  492.  
  493.         if(itemID == kTextInfo)
  494.             ((CNeoDemoDoc *)itsSupervisor)->fTextInfo = text;
  495.         else
  496.         if(itemID == kType)
  497.             ((CNeoDemoDoc *)itsSupervisor)->fTextType = text;
  498.  
  499.         return text;
  500.     }
  501.  
  502. }    /* CNeoDLOGDialog::AddDITLStatText */
  503.  
  504. /******************************************************************************
  505.  AddDITLEditText
  506.  
  507.      Add an edit text item.     The text font and size are controlled by the
  508.      fEditTextFont and fEditTextSize instance variables.
  509.  
  510. *******************************************************************************/
  511.  
  512. CPane *CNeoDLOGDialog::AddDITLEditText(short aWidth, short aHeight, short hEncl,
  513.                         short vEncl, CView *enclosure, tDITLItem *ditlItem)
  514. {
  515.     CNeoDialogText *text;
  516.  
  517.     text = new(CNeoDialogText);
  518.  
  519.     text->IDialogText(enclosure, this, aWidth, aHeight, hEncl, vEncl, sizFIXEDSTICKY, sizFIXEDSTICKY, -1);
  520.  
  521.     text->SetFontNumber(fEditTextFont);
  522.     if (fEditTextSize > 0)
  523.         text->SetFontSize(fEditTextSize);
  524.  
  525.     /* bug in CDLOGDialog - viewRect of text edit record is set from the current port
  526.        text size. So have to force viewRect.bottom same as destRect.bottom.
  527.     */
  528.     (**(text->macTE)).viewRect.bottom=aHeight;
  529.  
  530.     if (ditlItem->itemLength)
  531.         text->SetTextPtr((Ptr) ditlItem->itemData, ditlItem->itemLength);
  532.  
  533.     switch(itemID)
  534.     {
  535.     case kPICTName:
  536.         text->SetFontSize(12);    /* name is bigger */
  537.         text->SetAlignment(teJustCenter);
  538.         ((CNeoDemoDoc *)itsSupervisor)->fTextName = text;
  539.         break;
  540.  
  541.     case ksearchText:
  542.         text->Hide();             /* so tab skips this field when it's invis */
  543.         text->showBorder(TRUE);
  544.         ((CNeoDemoDoc *)itsSupervisor)->fSearchText = text;
  545.         break;
  546.  
  547.     case ktextBy:
  548.         ((CNeoDemoDoc *)itsSupervisor)->fTextBy = text;
  549.         break;
  550.  
  551.     case ktextDate:
  552.         ((CNeoDemoDoc *)itsSupervisor)->fTextDate = text;
  553.         break;
  554.  
  555.     case ktextCatalog:
  556.         ((CNeoDemoDoc *)itsSupervisor)->fTextCatalog = text;
  557.         break;
  558.  
  559.     case ktextKeywords:
  560.         ((CNeoDemoDoc *)itsSupervisor)->fTextKeywords = text;
  561.         break;
  562.     }
  563.  
  564.     return text;
  565.  
  566. }    /* CNeoDLOGDialog::AddDITLEditText */
  567.  
  568. /******************************************************************************
  569.  AddDITLIcon
  570.  
  571.      Add an icon
  572. ******************************************************************************/
  573.  
  574. CPane *CNeoDLOGDialog::AddDITLIcon(short aWidth, short aHeight, short hEncl,
  575.                         short vEncl, CView *enclosure, tDITLItem *ditlItem)
  576. {
  577.     CIconPane *icon;
  578.  
  579.     icon = new(CIconPane);
  580.     icon->IIconPane(enclosure, this, hEncl, vEncl,
  581.                 sizFIXEDSTICKY, sizFIXEDSTICKY, ditlItem->itemData[0], TRUE);
  582.  
  583.     return icon;
  584.  
  585. }    /* CNeoDLOGDialog::AddDITLIcon */
  586.  
  587. /******************************************************************************
  588.  AddDITLPicture
  589.  
  590.      Add a picture
  591. ******************************************************************************/
  592.  
  593. CPane *CNeoDLOGDialog::AddDITLPicture(short aWidth, short aHeight, short hEncl, short vEncl, CView *enclosure, tDITLItem *ditlItem)
  594. {
  595.     Point                pt;
  596.     CPaneBorder *        border;
  597.     CNDPicture *        pict;
  598.     CNDFilePicture *    fpict;
  599.  
  600.  
  601.     if (itemID == ksigPICT)            /* special item - handles click to show/hide lower portion */
  602.     {
  603.         FailNIL(pict = new(CNDPicture));
  604.         pict->INDPicture(ditlItem->itemData[0], enclosure, this,
  605.             aWidth, aHeight, hEncl, vEncl, sizFIXEDSTICKY, sizFIXEDSTICKY);
  606.  
  607.         ((CNeoDemoDoc *)itsSupervisor)->fSignal = pict;
  608.  
  609.         return pict;
  610.     }
  611.     else    /* main Picture object */
  612.     {
  613.         FailNIL(fpict = new(CNDFilePicture));
  614.         fpict->INDFilePicture(enclosure, this, aWidth, aHeight,
  615.             hEncl, vEncl, sizFIXEDSTICKY, sizFIXEDSTICKY);
  616.  
  617.         fpict->UsePICT(ditlItem->itemData[0]); /* pass resource ID of PICT */
  618.         border = new(CPaneBorder);
  619.         border->IPaneBorder(kBorderFrame);
  620.         border->SetPenSize(3, 3);    /* thick border like scrapbook's */
  621.         border->SetPattern(&qd.white);    /* not seen till it gets a click */
  622.  
  623.         fpict->SetBorder(border);
  624.  
  625.         ((CNeoDemoDoc *)itsSupervisor)->fPictObj = fpict;
  626.  
  627.         return fpict;
  628.     }
  629.  
  630. }    /* CNeoDLOGDialog::AddDITLPicture */
  631.  
  632. CNeoPopupPane *CNeoDLOGDialog::makePopup(short aID, CView *aEnclosure, short aWidth, short aHeight, short aHEncl, short aVEncl, short aSpace)
  633. {
  634.     short            saveFont;
  635.     short            saveSize;
  636.     CNeoPopupPane *    popup;
  637.  
  638.     saveFont = *SysFontFam;
  639.     saveSize = *SysFontSize;
  640.     *SysFontFam = geneva;
  641.     *SysFontSize = 9;
  642.     *LastSpExtra = -1L;                    // Signal to flush font cache
  643.  
  644.     popup = new CNeoPopupPane;
  645.     NeoFailNil(popup);
  646.     popup->INeoPopupPane(aID, aEnclosure, this, aWidth, aHeight, aHEncl, aVEncl, aSpace);
  647.  
  648.     *SysFontFam = saveFont;
  649.     *SysFontSize = saveSize;
  650.     *LastSpExtra = -1L;                    // Signal to flush font cache
  651.  
  652.     return popup;
  653. }
  654.  
  655. /******************************************************************************
  656.  AddDITLUserItem
  657.  
  658.      Add a user item. User items are converted to simple bordered panes
  659.      that use the fDefaultBorderPen thickness.
  660.      2 user items are line dividers.
  661.      1 user item is PICT border.
  662.      1 user item is place for popup menu.
  663. ******************************************************************************/
  664.  
  665. CPane *CNeoDLOGDialog::AddDITLUserItem(short aWidth, short aHeight, short hEncl,
  666.                         short vEncl, CView *enclosure, tDITLItem *ditlItem)
  667. {
  668.     CPane *            pane    = new(CPane);
  669.     Rect            margin;
  670.     CPaneBorder *    border;
  671.     CNeoPopupPane *    typePop;
  672.  
  673.     switch(itemID)
  674.     {
  675.         case kUserLineDivider2:
  676.             ((CNeoDemoDoc *)itsSupervisor)->fDivideLine = ditlItem->itemRect.bottom;
  677.             /* fall through is intentional */
  678.  
  679.         case kUserLineDivider1:
  680.             pane->IPane(enclosure, this, aWidth, -1, hEncl, vEncl,
  681.                         sizFIXEDSTICKY, sizFIXEDSTICKY);
  682.             border = new(CPaneBorder);
  683.             border->IPaneBorder(kBorderFrame);
  684.             border->SetPenSize(fDefaultBorderPen, fDefaultBorderPen);
  685.  
  686.             pane->SetBorder(border);
  687.  
  688.             break;
  689.  
  690.  
  691.         case kUserType:
  692.             typePop = makePopup(kTypePopupMenuID, enclosure, aWidth, aHeight, hEncl, vEncl, 5);
  693.             pane = (CPane*)typePop;
  694.             ((CNeoDemoDoc *)itsSupervisor)->fPopObj = typePop;
  695.             break;
  696.  
  697.         case kUserFilm:
  698.             typePop = makePopup(kFilmPopupMenuID, enclosure, aWidth, aHeight, hEncl, vEncl, 29);
  699.             pane = (CPane*)typePop;
  700.             ((CNeoDemoDoc *)itsSupervisor)->fPopFilm = typePop;
  701.             break;
  702.  
  703.         case kUserBody:
  704.             typePop = makePopup(kBodyPopupMenuID, enclosure, aWidth, aHeight, hEncl, vEncl, 25);
  705.             pane = (CPane*)typePop;
  706.             ((CNeoDemoDoc *)itsSupervisor)->fPopBody = typePop;
  707.             break;
  708.  
  709.         case kUserFocal:
  710.             typePop = makePopup(kFocalPopupMenuID, enclosure, aWidth, aHeight, hEncl, vEncl, 24);
  711.             pane = (CPane*)typePop;
  712.             ((CNeoDemoDoc *)itsSupervisor)->fPopFocal=typePop;
  713.             break;
  714.  
  715.         case kUserFStop:
  716.             typePop = makePopup(kFStopPopupMenuID, enclosure, aWidth, aHeight, hEncl, vEncl, 18);
  717.             pane = (CPane*)typePop;
  718.             ((CNeoDemoDoc *)itsSupervisor)->fPopFStop = typePop;
  719.             break;
  720.  
  721.         case kUserExposure:
  722.             typePop = makePopup(kExposurePopupMenuID, enclosure, aWidth, aHeight, hEncl, vEncl, 6);
  723.             pane = (CPane*)typePop;
  724.             ((CNeoDemoDoc *)itsSupervisor)->fPopExposure = typePop;
  725.             break;
  726.     }
  727.  
  728.     return pane;
  729.  
  730. }    /* CNeoDLOGDialog::AddDITLUserItem */
  731.  
  732.  
  733. /******************************************************************************
  734.  AddOverloadedItem
  735.  
  736.      View types that have no direct dialog mgr analog may be added
  737.      by overloading the static text item. The types support are:
  738.  
  739.      TYPE                        STATIC TEXT
  740.      ----                        -----------
  741.  
  742.      Any Pane resource            @$ClassName$ResType$ResID
  743.                                  e.g. @CPopupMenuPane$Popm$1000
  744.                                  would create a CPopupMenuPane from the template in
  745.                                  the resource 'Popm' 1000. The size and location
  746.                                  of the pane are taken from the dialog item rect,
  747.                                  not from the resource.
  748.  
  749.      CRadioGroupPane                @RadioGroupPane
  750.  
  751.  
  752.      CIntegerText                @# must be first two characters
  753.                                  To supply min and max values enter
  754.                                  @#<min>#<max>,
  755.  
  756.                                  e.g. @#100#200 (see Demo.π.rsrc DITL 1026)
  757.  
  758.      CNeoDialogText/ constraints    @!!        - creates required field, no max length
  759.                                  @!<num> - not required, max length is num
  760.                                            e.g. @!10 max length is 10
  761.                                  @!!<num> - required field with max length
  762.                                               e.g. @!!10
  763.  
  764.      Other overloaded types may be created by overriding this method.
  765.  
  766. ******************************************************************************/
  767.  
  768. CPane *CNeoDLOGDialog::AddOverloadedItem(StringPtr itemText, short aWidth, short aHeight,
  769.                     short hEncl, short vEncl,
  770.                     CView *enclosure, tDITLItem *ditlItem)
  771. {
  772.     Str255            numStr;
  773.     short            index;
  774.  
  775.     if (Length(itemText) == 0) return NULL;
  776.  
  777.     if (itemText[1] == '$')                // Create from resource
  778.     {
  779.         ResType     type;
  780.         long        resID;
  781.         Str255      className;
  782.         CPane        *newPane;
  783.         PaneTemp     savedTemplate, *theTemp;
  784.         Handle        templateRes;
  785.         SignedByte    savedState;
  786.  
  787.             // collect the class name, resource type and ID
  788.         index = 2;
  789.         CollectUntil('$', itemText, &index, className);
  790.         if (Length(className) == 0)
  791.             return nil;
  792.  
  793.         ++index;
  794.         CollectUntil('$', itemText, &index, numStr);
  795.         if (Length(numStr) == 0)
  796.             return nil;
  797.  
  798.         BlockMove(&numStr[1], &type, sizeof(type));
  799.         ++index;
  800.         CollectUntil(' ', itemText, &index, numStr);
  801.         if (Length(numStr) == 0)
  802.             return nil;
  803.  
  804.         StringToNum(numStr, &resID);
  805.  
  806.             // get the resource, save the location and size, then
  807.             // restore it after the pane is created.
  808.  
  809.         templateRes = GetResource(type, resID);
  810.         FailNILRes(templateRes);
  811.         savedState = HGetState(templateRes);
  812.         HNoPurge(templateRes);
  813.  
  814.         theTemp = *(PaneTemp**) templateRes;
  815.         savedTemplate = **(PaneTemp**)templateRes;
  816.         theTemp->width = aWidth;
  817.         theTemp->height = aHeight;
  818.         theTemp->hEncl = hEncl;
  819.         theTemp->vEncl = vEncl;
  820.  
  821.             // now make the pane
  822.  
  823.         newPane = (CPane *)new_by_name(PtoCstr(className));
  824.         if (!newPane) Failure(paramErr, excNewByNameFailed);
  825.  
  826.         newPane->IViewRes(type, resID, enclosure, this);
  827.  
  828.         HSetState(templateRes, savedState);
  829.         **(PaneTemp**) templateRes = savedTemplate; /* TCL 1.1.1 DLP 9/18/91 */
  830.  
  831.         return newPane;
  832.     }
  833.     else if (itemText[1] == '#')        // Create a CIntegerText
  834.     {
  835.         long            min, max;
  836.         CIntegerText    *text  = new CIntegerText;
  837.  
  838.         text->IIntegerText(enclosure, this, aWidth, aHeight, hEncl, vEncl,
  839.                     sizFIXEDSTICKY, sizFIXEDSTICKY, -1);
  840.  
  841.         text->SetFontNumber(fEditTextFont);
  842.         if (fEditTextSize > 0)
  843.             text->SetFontSize(fEditTextSize);
  844.  
  845.         index = 2;
  846.         min = MINLONG;
  847.         max = MAXLONG;
  848.  
  849.         CollectUntil('#', itemText, &index, numStr);
  850.         if (Length(numStr)) StringToNum(numStr, &min);
  851.  
  852.             // check if string not exhausted and have another '#'
  853.  
  854.         if ((index < Length(itemText)) && (itemText[index] == '#'))
  855.         {
  856.             index++;    // move past delimiter
  857.             CollectUntil('#', itemText, &index, numStr);
  858.             if (Length(numStr)) StringToNum(numStr, &max);
  859.         }
  860.         text->SpecifyRange(min, max);
  861.  
  862.         return text;
  863.  
  864.     }
  865.     else if (itemText[1] == '!')    // Create a CNeoDialogText with constraints
  866.     {
  867.         Boolean        required    = FALSE;
  868.         short        index        = 2;
  869.         long        maxChars    = MAXLONG;
  870.  
  871.         CNeoDialogText *text = new CNeoDialogText;
  872.  
  873.         text->IDialogText(enclosure, this, aWidth, aHeight,
  874.                     hEncl, vEncl,
  875.                     sizFIXEDSTICKY, sizFIXEDSTICKY, -1);
  876.  
  877.         text->SetFontNumber(fEditTextFont);
  878.         if (fEditTextSize > 0)
  879.             text->SetFontSize(fEditTextSize);
  880.  
  881.         // if next char is another '!', make this a required field
  882.         if (itemText[2] == '!')
  883.         {
  884.             index++;
  885.             required = TRUE;
  886.         }
  887.         // next text, if any, is max number of chars, no
  888.         // trailing delimiter is required, just collect until end of string
  889.         CollectUntil('!', itemText, &index, numStr);
  890.         if (Length(numStr)) StringToNum(numStr, &maxChars);
  891.  
  892.         text->SetConstraints(required, maxChars);
  893.  
  894.         return text;
  895.     }
  896.     else if (EqualString(itemText, "\pRadioGroupPane", FALSE, FALSE))
  897.     {
  898.         CPaneBorder    *        border;
  899.         CRadioGroupPane *    group    = new CRadioGroupPane;
  900.  
  901.         group->IRadioGroupPane(enclosure, this, aWidth, aHeight,
  902.                         hEncl, vEncl, sizFIXEDSTICKY, sizFIXEDSTICKY);
  903.         border = new CPaneBorder;
  904.         border->IPaneBorder(kBorderFrame);
  905.         border->SetPenSize(fDefaultBorderPen, fDefaultBorderPen);
  906.         group->SetBorder(border);
  907.  
  908.         return group;
  909.     }
  910.  
  911.     return NULL;
  912.  
  913. }    /* CNeoDLOGDialog::AddOverloadedItem */
  914.  
  915. static void CollectUntil(char delimiter, StringPtr text, short *index,
  916.                 StringPtr returnStr)
  917. {
  918.     short    i        = *index;
  919.     short    limit    = Length(text);
  920.  
  921.     Length(returnStr) = 0;
  922.     while ((text[i] != delimiter) && (i <= limit)) {
  923.         returnStr[ ++returnStr[0]] = text[i++];
  924.     }
  925.     if (i > limit) i = limit;
  926.     *index = i;
  927.  
  928. }
  929.  
  930. /******************************************************************************
  931.   ProviderChanged
  932.  
  933.       Respond to a change in a provider. All the dialog items are implicit
  934.       providers to the dialog. When an item becomes the gopher, it will notify
  935.       the dialog. If the gopher is a pane, the dialog will attempt to scroll
  936.       it into view.
  937. ******************************************************************************/
  938.  
  939. void CNeoDLOGDialog::ProviderChanged(CCollaborator *aProvider, long reason, void* info)
  940. {
  941.     short    index;
  942.     short    count;
  943.  
  944.     switch (reason) {
  945.     case NeoDialogBordersChanged:
  946.         ((CNeoDemoDoc *)itsSupervisor)->showBorders(*(Boolean *)info);
  947.         break;
  948.     }
  949.  
  950.     inherited::ProviderChanged(aProvider, reason, info);
  951. }    /* CNeoDLOGDialog::ProviderChanged */
  952.  
  953. void    CNeoDLOGDialog::DoCommand(long    theCommand)
  954. {
  955.     Boolean        pass    = TRUE;
  956.     CNDImage *    image;
  957.  
  958.     switch (theCommand) {
  959.     case cmdCut:
  960.         pass = ((CNeoDemoDoc *)itsSupervisor)->doCutCopy(TRUE);
  961.         break;
  962.  
  963.     case cmdCopy:
  964.         pass = ((CNeoDemoDoc *)itsSupervisor)->doCutCopy(FALSE);
  965.         break;
  966.  
  967.     case cmdPaste:
  968.         pass = ((CNeoDemoDoc *)itsSupervisor)->doPaste();
  969.         break;
  970.     }
  971.  
  972.     if (pass)
  973.         inherited::DoCommand(theCommand);        /* pass it on */
  974. }
  975.  
  976. /******************************************************************************
  977.  DoKeyDown {OVERRIDE}
  978.  
  979.      Handle keypresses in a DialogText object. Keys that have a special meaning
  980.      in a dialog (tab, return, enter, and Escape) are passed to itsSupervisor,
  981.      all other keys are passed through to the superclass.
  982. ******************************************************************************/
  983.  
  984. void CNeoDLOGDialog::DoKeyDown(char theChar, Byte keyCode, EventRecord *macEvent)
  985. {
  986.     if (theChar == '\t')
  987.         ((CNeoDemoDoc *)itsSupervisor)->showBorders(TRUE);
  988.  
  989.     inherited::DoKeyDown(theChar, keyCode, macEvent);
  990.  
  991. }    /* CNeoDLOGDialog::DoKeyDown */
  992.  
  993. Boolean CNeoDLOGDialog::isZoomed(void)
  994. {
  995.     return ((CNeoDemoDoc *)itsSupervisor)->fSignal->isZoomed();
  996. }
  997.  
  998. /******************************************************************************
  999.  Update
  1000.  
  1001.         Update the contents of a window
  1002.  ******************************************************************************/
  1003.  
  1004. void    CNeoDLOGDialog::Update()
  1005. {
  1006.     CNeoDatabase *    database    = gNeoDatabase;
  1007.     CNeoDemoDoc *    document    = (CNeoDemoDoc *)itsSupervisor;
  1008.  
  1009.     if (document->itsFile)
  1010.         gNeoDatabase = (CNeoDatabase *)document->itsFile;
  1011. #ifdef qNeoDebug
  1012.     else
  1013.         NeoAssert(FALSE);
  1014. #endif
  1015.  
  1016.     inherited::Update();
  1017.  
  1018.     gNeoDatabase = database;
  1019. }
  1020.  
  1021.